﻿using System;
using System.IO;
using Mersiv.App.Client.Logging;
using Mersiv.Lib.Wrapper;

namespace Mersiv.App.Client.Controller
{

  internal class HgRepositoryFileSystemMonitor
  {

    #region FileIndexEvent

    /// <summary>
    /// TODO: Add an event "type"?
    /// </summary>
    /// <param name="path"></param>
    public delegate void FileIndexEvent(string path);

    public event FileIndexEvent FileIndexUpdate;
    private void OnFileIndexUpdate(string path)
    {
      if (this.FileIndexUpdate != null)
      {
        this.FileIndexUpdate(path);
      }
    }

    //public event FileIndexEvent FileIndexError;
    //private void OnFileIndexError(string path)
    //{
    //  if (this.FileIndexError != null)
    //  {
    //    this.FileIndexError(path);
    //  }
    //}

    //public event FileIndexEvent FileIndexCompleted;
    //private void OnFileIndexCompleted(string path)
    //{
    //  if (this.FileIndexCompleted != null)
    //  {
    //    this.FileIndexCompleted(path);
    //  }
    //}

    #endregion

    private FileSystemWatcher fileSystemWatcher;
    private FileSystemEventHandler fileSystemEventHandler_Created;
    private FileSystemEventHandler fileSystemEventHandler_Changed;
    private FileSystemEventHandler fileSystemEventHandler_Deleted;
    private RenamedEventHandler fileSystemEventHandler_Renamed;
    private ErrorEventHandler fileSystemEventHandler_Error;

    #region HgRepository
    private HgRepository hgRpository;
    public HgRepository Repository {
      get
      {
        return this.hgRpository;
      }
      set
      {
        // remove previous
        if (this.hgRpository != null)
        {
          this.fileSystemWatcher.EnableRaisingEvents = false;
          this.fileSystemWatcher.Created -= this.fileSystemEventHandler_Created;
          this.fileSystemWatcher.Changed -= this.fileSystemEventHandler_Changed;
          this.fileSystemWatcher.Deleted -= this.fileSystemEventHandler_Deleted;
          this.fileSystemWatcher.Renamed -= this.fileSystemEventHandler_Renamed;
          this.fileSystemWatcher.Error -= this.fileSystemEventHandler_Error;
        }
        this.hgRpository = value;
        this.fileSystemWatcher.Path = this.hgRpository.WorkingDirectory;
        this.fileSystemWatcher.EnableRaisingEvents = true;
        this.fileSystemWatcher.IncludeSubdirectories = true;
        this.fileSystemWatcher.Created += this.fileSystemEventHandler_Created;
        this.fileSystemWatcher.Changed += this.fileSystemEventHandler_Changed;
        this.fileSystemWatcher.Deleted += this.fileSystemEventHandler_Deleted;
        this.fileSystemWatcher.Renamed += this.fileSystemEventHandler_Renamed;
        this.fileSystemWatcher.Error += this.fileSystemEventHandler_Error;
      }
    }
    #endregion

    public HgRepositoryFileSystemMonitor()
    {
      this.fileSystemWatcher = new FileSystemWatcher();
      this.fileSystemEventHandler_Created = new FileSystemEventHandler(this.fileSystemWatcher_Created);
      this.fileSystemEventHandler_Changed = new FileSystemEventHandler(this.fileSystemWatcher_Changed);
      this.fileSystemEventHandler_Deleted = new FileSystemEventHandler(this.fileSystemWatcher_Deleted);
      this.fileSystemEventHandler_Renamed = new RenamedEventHandler(this.fileSystemWatcher_Renamed);
      this.fileSystemEventHandler_Error = new ErrorEventHandler(this.fileSystemWatcher_Error);
    }

    #region Event Handlers

    //
    // TODO: Pass events on to event handlers
    //

    private void fileSystemWatcher_Changed(object sender, FileSystemEventArgs e)
    {
      LogManager.Instance.Add(e.FullPath + " CHANGED: " + e.ChangeType.ToString());
    }

    private void fileSystemWatcher_Created(object sender, FileSystemEventArgs e)
    {
    }

    private void fileSystemWatcher_Deleted(object sender, FileSystemEventArgs e)
    {
    }

    private void fileSystemWatcher_Renamed(object sender, RenamedEventArgs e)
    {
    }

    private void fileSystemWatcher_Error(object sender, ErrorEventArgs e)
    {
      LogManager.Instance.Add(e.ToString());
    }

    #endregion

  }

}